using Microsoft.Xna.Framework;
using SCSEngine.Sprite;
using SCSEngine.Utils.Entities.Component.Number;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SCSEngine.Utils.Entities.Component.SpriteComponents
{
    public interface ISpriteModelComponent : IGameComponent
    {
        IVector2Component Position { get; }
        IVector2Component Origin { get; }
        INumberComponent Scale { get; }
        INumberComponent Rotation { get; }
        SpriteEffectsComponent Effect { get; }
        IColorComponent Color { get; }
        INumberComponent Depth { get; }

        ISpriteModel Value { get; }
    }

    public class SpriteModelComponent : ISpriteModelComponent
    {
        public IVector2Component Position { get; private set; }

        public IVector2Component Origin { get; private set; }

        public INumberComponent Scale { get; private set; }

        public INumberComponent Rotation { get; private set; }

        public SpriteEffectsComponent Effect { get; private set; }

        public IColorComponent Color { get; private set; }

        public INumberComponent Depth { get; private set; }

        private ISpriteModel spriteModel;

        public SpriteModelComponent()
        {
            this.Position = new Vector2Component();
            this.Origin = new Vector2Component();
            this.Scale = new NumberComponent(1f);
            this.Rotation = new NumberComponent();
            this.Effect = new SpriteEffectsComponent();
            this.Color = new ColorComponent();
            this.Depth = new NumberComponent();

            this.spriteModel = new ComponentsSpriteModel(this);
        }

        public SpriteModelComponent(IVector2Component position, IVector2Component origin,
            INumberComponent scale, INumberComponent rotation, SpriteEffectsComponent effect,
            IColorComponent color, INumberComponent depth)
        {
            if (position != null)
            {
                this.Position = position;
            }
            else
            {
                this.Position = new Vector2Component();
            }

            if (origin != null)
            {
                this.Origin = origin;
            }
            else
            {
                this.Origin = new Vector2Component();
            }

            if (scale != null)
            {
            }
            else
            {
                this.Scale = new NumberComponent(1f);
            }

            if (rotation != null)
            {
                this.Rotation = rotation;
            }
            else
            {
                this.Rotation = new NumberComponent();
            }

            if (effect != null)
            {
                this.Effect = effect;
            }
            else
            {
                this.Effect = new SpriteEffectsComponent();
            }

            if (color != null)
            {
                this.Color = color;
            }
            else
            {
                this.Color = new ColorComponent();
            }

            if (depth != null)
            {
                this.Depth = depth;
            }
            else
            {
                this.Depth = new NumberComponent();
            }

            this.spriteModel = new ComponentsSpriteModel(this);
        }

        public SpriteModelComponent(IGameEntity entity)
        {
            IVector2Component position = entity.GetComponent<IVector2Component>(ComponentKeys.Position);
            if (position != null)
            {
                this.Position = position;
            }
            else
            {
                this.Position = new Vector2Component();
            }

            IVector2Component origin = entity.GetComponent<IVector2Component>(ComponentKeys.Origin);
            if (origin != null)
            {
                this.Origin = origin;
            }
            else
            {
                this.Origin = new Vector2Component();
            }

            INumberComponent scale = entity.GetComponent<INumberComponent>(ComponentKeys.Scale);
            if (scale != null)
            {
                this.Scale = scale;
            }
            else
            {
                this.Scale = new NumberComponent(1f);
            }

            INumberComponent rotation = entity.GetComponent<INumberComponent>(ComponentKeys.Rotation);
            if (rotation != null)
            {
                this.Rotation = rotation;
            }
            else
            {
                this.Rotation = new NumberComponent();
            }

            SpriteEffectsComponent effect = entity.GetComponent<SpriteEffectsComponent>(ComponentKeys.SpriteEffects);
            if (effect != null)
            {
                this.Effect = effect;
            }
            else
            {
                this.Effect = new SpriteEffectsComponent();
            }

            IColorComponent color = entity.GetComponent<IColorComponent>(ComponentKeys.Color);
            if (color != null)
            {
                this.Color = color;
            }
            else
            {
                this.Color = new ColorComponent();
            }

            INumberComponent depth = entity.GetComponent<INumberComponent>(ComponentKeys.Depth);
            if (depth != null)
            {
                this.Depth = depth;
            }
            else
            {
                this.Depth = new NumberComponent();
            }

            this.spriteModel = new ComponentsSpriteModel(this);
        }

        public void Initialize()
        {
        }

        public ISpriteModel Value
        {
            get { return this.spriteModel; }
        }

        private class ComponentsSpriteModel : ISpriteModel
        {
            ISpriteModelComponent modelComponent;

            public ComponentsSpriteModel(ISpriteModelComponent sprModelComponent)
            {
                this.modelComponent = sprModelComponent;
            }

            public Vector2 Position
            {
                get
                {
                    return this.modelComponent.Position.Value;
                }
                set
                {
                    this.modelComponent.Position.Value = value;
                }
            }

            public Vector2 Origin
            {
                get
                {
                    return this.modelComponent.Origin.Value;
                }
                set
                {
                    this.modelComponent.Origin.Value = value;
                }
            }

            public float Scale
            {
                get
                {
                    return this.modelComponent.Scale.Value;
                }
                set
                {
                    this.modelComponent.Scale.Value = value;
                }
            }

            public float Rotation
            {
                get
                {
                    return this.modelComponent.Rotation.Value;
                }
                set
                {
                    this.modelComponent.Rotation.Value = value;
                }
            }

            public Microsoft.Xna.Framework.Graphics.SpriteEffects Effect
            {
                get
                {
                    return this.modelComponent.Effect.Value;
                }
                set
                {
                    this.modelComponent.Effect.Value = value;
                }
            }

            public Color Color
            {
                get
                {
                    return this.modelComponent.Color.Value;
                }
                set
                {
                    this.modelComponent.Color.Value = value;
                }
            }

            public float Depth
            {
                get
                {
                    return this.modelComponent.Depth.Value;
                }
                set
                {
                    this.modelComponent.Depth.Value = value;
                }
            }

            public void Initialize()
            {
            }
        }
    }
}
